% !Mode:: "TeX:UTF-8"

\chapter{项目三与项目四后端}

\section{项目需求}
本项目参照 “饿了么官网网页版”制作。本项目专注于完成点餐业务线功能，“饿了么官网”中的其它功能暂不涉及。
以下内容大致概括了本系统的项目需求：

(1)用户信息管理:在用户进入系统前要求客户进行登录，未注册的用户需要注册后方可登录。登录时需要对用户Id和密码进行
校验，正确后即可登录。

(2)商家信息管理：向用户提供商家名称、地址、图片以及食物等相关信息。

(3)购物车及订单管理：允许用户向购物车中添加或删除食物，并生成相关订单。

(4)用户地址管理：一个用户可以拥有多个收货地址并对地址进行修改，保存。

\subsection{业务流程}
项目的具体流程如图~\ref{fig:bpf}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{BPF}
  \caption{业务流程}\label{fig:bpf}
  \vspace{\baselineskip}
\end{figure}

\section{项目设计}
\subsection{数据库设计}
项目三、四数据库的设计与数据相同，且与参考文件保持一致，故本文不再赘述。

\subsection{架构设计与UML图}

项目采用MVC架构设计如图~\ref{fig:mvc}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{MVC}
  \caption{MVC架构}\label{fig:mvc}
  \vspace{\baselineskip}
\end{figure}

项目三、四基于Servlet的简易MVC架构，采用约定优于配置的原则来搭建简易MVC框架。
项目三、四的分层结构基本相同，其中数据库连接层在项目三中为Dao层，在项目四中为Mapper层。

Controller层UML图如图~\ref{fig:controller}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{controller}
  \caption{Controller层UML图}\label{fig:controller}
  \vspace{\baselineskip}
\end{figure}

Service层UML图如图~\ref{fig:service}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{service}
  \caption{Service层UML图}\label{fig:service}
  \vspace{\baselineskip}
\end{figure}

Dao/Mapper层UML图如图~\ref{fig:dao}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{dao.png}
  \caption{Dao/Mapper层UML图}\label{fig:dao}
  \vspace{\baselineskip}
\end{figure}

\newpage
\subsection{接口设计}
与参考视频中的接口设计不同，我们设计了RESTful风格的接口。
RESTful API中，URL中只使用名词来指定资源，原则上不使用动词。多人协作时，统一风格，可提高沟通效率。

\subsubsection{business}
(1)get+Business/OrderTypeId

参数：orderTypeId

返回值：business数组

功能：根据点餐分类编号查询所属商家信息

(2)get+Business/BusinessId

参数：businessId

返回值：business对象

功能：根据商家编号查询商家信息


\subsubsection{food}
(1)get方法+Food/BusinessId

参数：businessId

返回值：food数组

功能：根据商家编号查询所属食品信息


\subsubsection{cart}
(1)get+Cart/CartList

参数：userId、businessId（可选）

返回值：cart数组（多对一：所属商家信息、所属食品信息）

功能：根据用户编号查询此用户所有购物车信息;根据用户编号和商家编号，查询此用户购物车中某个商家的所有购物车信息


(2)post+Cart/Order

参数：userId、businessId、foodId

返回值：int（影响的行数）

功能：向购物车表中添加一条记录


参数：userId、businessId、foodId、quantity

返回值：int（影响的行数）

功能：根据用户编号、商家编号、食品编号更新数

(3)put+Cart/Order

参数：userId、businessId、foodId、quantity

返回值：int（影响的行数）

功能：根据用户编号、商家编号、食品编号更新数量

(4)delete+Cart/Order

参数：userId、businessId、foodId（可选）

返回值：int（影响的行数）

功能：根据用户编号、商家编号、食品编号删除购物车表中的一条食品记录;根据用户编号、商家编号删除购物车表中的多条条记录


\subsubsection{deliveryAddress}
(1)get+DeliveryAddress/UserId

参数：userId

返回值：deliveryAddress数组

功能：根据用户编号查询所属送货地址

(2)get+DeliveryAddress/DaId

参数：daId

返回值：deliveryAddress对象

功能：根据送货地址编号查询送货地址

(3)post+DeliveryAddress/DaId

参数：contactName、contactSex、contactTel、address、userId

返回值：int（影响的行数）

功能：向送货地址表中添加一条记录

(4)put+DeliveryAddress/DaId

参数：daId、contactName、contactSex、contactTel、address、userId

返回值：int（影响的行数）

功能：根据送货地址编号更新送货地址信息

(5)delete+DeliveryAddress/DaId

参数：daId

返回值：int（影响的行数）

功能：根据送货地址编号删除一条记录


\subsubsection{orders}
(1)post+Orders/OrdersId

参数：userId、businessId、daId、orderTotal

返回值：int（订单编号）

功能：根据用户编号、商家编号、订单总金额、送货地址编号向订单表中添加一条记录，
并获取自动生成的订单编号，
然后根据用户编号、商家编号从购物车表中查询所有数据，批量添加到订单明细表中，
然后根据用户编号、商家编号删除购物车表中的数据。

(2)get+Orders/OrdersId

参数：orderId

返回值：orders对象（包括多对一：商家信息； 一对多：订单明细信息）

功能：根据订单编号查询订单信息，包括所属商家信息，和此订单的所有订单明细信息

(3)get+Orders/userId

参数：userId

返回值：orders数组（包括多对一：商家信息； 一对多：订单明细信息）

功能：根据用户编号查询此用户的所有订单信息


\subsubsection{user}
(1)get+User/Login

参数：userId、password

返回值：user对象

功能：根据用户编号与密码查询用户信息

(2)get+User/UserId

参数：userId

返回值：int（返回行数）

功能：根据用户编号查询用户表返回的行数

(3)post+User/UserId

参数：userId、password、userName、userSex

返回值：int（影响的行数）

功能：向用户表中添加一条记录

\newpage


\section{项目测试}
利用postman对接口进行测试，若能正确返回结果，则表明接口实现正确。如图~\ref{fig:postman}~所示。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{postman.png}
  \caption{postman测试接口}\label{fig:postman}
  \vspace{\baselineskip}
\end{figure}

\section{项目部署}
\subsection{服务器配置}
在华为云上有免费的服务器可以供我们使用：
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{hwy-1.png}
  \caption{华为云服务器}\label{fig:hwy-1}
  \vspace{\baselineskip}
\end{figure}

在配置好服务器的硬件配置后，我们还要对服务器的端口进行配置。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{hwy-2.png}
  \caption{服务器端口配置}\label{fig:hwy-2}
  \vspace{\baselineskip}
\end{figure}

\newpage
之后借助宝塔助手，在服务器上安装MySQL、tomcat等必需的软件。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{hwy-3.png}
  \caption{服务器软件安装}\label{fig:hwy-3}
  \vspace{\baselineskip}
\end{figure}

\subsection{相关文件上传服务器}
导出sql文件并且将springboot导出为jar包上传至服务器。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.5\textwidth]{sql.png}
  \caption{sql文件导出}\label{fig:sql}
  \vspace{\baselineskip}
\end{figure}

\begin{figure}[htbp]
  \centering
  \includegraphics[width=0.5\textwidth]{jar.png}
  \caption{导出jar包}\label{fig:jar}
  \vspace{\baselineskip}
\end{figure}
\newpage
\section{开发过程记录}
\subsection{项目三后端开发记录}
8月20日之前，简单学习JDBC知识，配置项目三开发所需环境。

8月20日到8月26日，参照视频顺序完成了项目三后端。项目三由刘京宗完成。

部分提交记录如下图。
全部提交记录可在gitee仓库中查看。

\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{043_prj3-process.png}
  \caption{项目三部分开发记录}\label{fig:prj3-process}
  \vspace{\baselineskip}
\end{figure}

\subsection{项目四后端开发记录}

由于需要准备上学期的考试，项目四在配置完相关环境后进行的第一次提交是在9月5日。

9月5日到9月12日，参照视频顺序完成了项目四后端。项目四由刘京宗和田欣悦共同完成。
其中田欣悦主要负责food、cart、user模块，刘京宗负责剩余模块。

部分提交记录如下图。
全部提交记录可在gitee仓库中查看。
\begin{figure}[htbp]
  \centering
  \includegraphics[width=1\textwidth]{043_prj4-process.png}
  \caption{项目四部分开发记录}\label{fig:prj4-process}
  \vspace{\baselineskip}
\end{figure}

\newpage
\section{项目特色}
1.虽然项目三和项目四实现的功能相同，但项目四相较于项目三具有诸多优势。
例如：springboot内嵌了servlet容器，降低了对环境的要求；实现了自动配置，
避免了编写大量的样板代码，减少了大量的开发时间。

2.虽然我们的项目大部分与教学视频与参考文件保持一致，但我们摒弃了视频中的接口设计
采用RESTful风格的接口设计。

3.由于我们后端的进度略快于前端，因此我们完成项目四后将其部署到华为云上。这样前端同学在开发
时可以直接调用后端，无需再自拟数据。
\newpage
\section{遇到的问题与解决方案}
在项目初期由于视频中使用的IDE是SpringToolSuite(STS)，而我本地使用的IDE为IntelliJ IDEA。因此起初在配置环境时遇到了一些困难，
但好在网上有较多的IDEA的使用教程，这一问题得以顺利解决。并且在对IDEA的使用较为熟练后，IDEA的诸多功能一定程度上也提高了我的开发效率。

由于教学视频的细致讲解和参考文档详细记录，整体的开发过程是比较顺利的。当然，开发过程中也遇到了一些bug，
这些bug多出现在Dao/Mapper层,往往是由于我sql语句编写错误所导致。这也反映出我对数据库的相关操作掌握不够熟练，
但幸运的是，这类bug是比较容易解决的，这也提醒我在编写程序时要认真细致。

在项目部署的时候，遇到的一个bug令我影响深刻。在我将导出的sql文件和jar包上传到服务器后，对接口进行了测试。奇怪
的是，所有关于deliveryAddress的接口均无法返回正确结果。在我反复确认了数据库相关字段和后端相关程序无误后，我又
查阅了服务器的项目日志，显示数据库没有deliveryAddress这一数据表。借助网络查询后，得知MySQL
在Windows中表名不区分大小写，而在Linux系统下是严格区分大小写的。在更改了sql文件中的表名后，这一问题得以顺利解决。

\section{总结与反思}

在这次软件工程综合实践中，我主要参与了项目三和项目四的后端开发。通过这次实践，我对软件
开发的基本流程有了一定了解，对后端开发中MVC的层次设计模型也有了一定认识。同时，
这次实践也增强了我的编码与调试能力，对Spring Boot这一框架有了初步了解。尤其是在开发项目
四时，Spring Boot框架和MyBatis框架极大的提高了开发效率，略去了项目三中诸多冗余的代码。再配合上
IDEA这一强大IDE，让人不禁感概开发程序竟可以如此的快捷高效。此外对于项目开发过程中的bug，
通过查阅参考书目、互联网检索等方法得以解决，主动获取知识能力和意识及独立解决问题的能力得以提升。
在项目结束后，学习latex编写文档，文档写作能力得以提升。

这次实践，除了专业知识的掌握，更重要的是团队协作能力的提升。“三人行，则必有我师”，小组的其他三位成员
认真负责，是我学习的榜样。在协作完成项目的过程中，我们积极交流，每个人各司其职，最终顺利完成了这一实践。

“往者不可谏，来者犹可追”。这次实践虽然暂时告一段落，但也暴露我编码能力不足，编码时不够认真细致等问题。
今后仍需戒骄戒躁继续努力。